"""
Created on Jul 12, 2010

@author: adolfo
"""
from core import SMSAppStoreDispatcher
from gammu_sms_gateway import GammuSMSGateway
from kannel_sms_gateway import KannelSMSGateway
from springpython.config import PythonConfig, Object
from springpython.database.factory import MySQLConnectionFactory,\
    SQLServerConnectionFactory
from schema_reader import ApplicationReader, FormReader
from threading import Thread
import logging
import logging.handlers
import platform

_logger = logging.getLogger("mx.org.came.application_context")

class SMSAppStoreConfig(PythonConfig):
    """Application context configuration for the SMSAppStore project.
    This is where SMSAppStore keeps all its configuration, and resources
    (or at least should).
    For more information, visit `Spring Python's home page
    <http://springpython.webfactional.com/>`_."""

    def __init__(self):
        PythonConfig.__init__(self)

    @Object
    def root_logger(self):
        """Configures the loggers to be used by the application and returns
        the root logger. This object is never explicitly used by the system,
        since Spring Python eagerly creates it, and by doing so, the logging
        is configured"""

        LOG_FILENAME = "/tmp/SMSAppStore.log"
        LOG_FORMAT = "%(asctime)s - [%(name)s] - [%(levelname)s] - %(message)s"

        #File logging configuration
        file_handler = logging.handlers.RotatingFileHandler(
                LOG_FILENAME,
                maxBytes=2000000,
                backupCount=5)
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(logging.Formatter(LOG_FORMAT))
        logging.getLogger().addHandler(file_handler)

        #Console logging configuration
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.DEBUG)
        console_handler.setFormatter(logging.Formatter(LOG_FORMAT))
        logging.getLogger().addHandler(console_handler)

        #Logging levels for the different application packages
        logging.getLogger().setLevel(logging.DEBUG)
        logging.getLogger("mx.org.came").setLevel(logging.DEBUG)

        return logging.getLogger()

    @Object
    def gammu_connection_factory(self):
        """Configures the database connection factory to be used to query
        Gammu's database.
        """
        connection_factory = MySQLConnectionFactory(username = "root"
                                                    , password = "password"
                                                    , hostname = "localhost"
                                                    , db = "smsd")
        return connection_factory

    @Object
    def sms_gateway(self):
        """Configures the instance of SMSGateway to be used by the application
        to send and receive SMS messages.
        """
        gateway = None
        os_name = platform.system()
        if os_name == "Linux":
            _logger.info("Using Kannel as SMS Gateway.")
            gateway = KannelSMSGateway(notification_server_address = "localhost"
                                       , notification_server_port = 55555
                                       , kannel_server_address = "127.0.0.1"
                                       , kannel_server_port = 13013
                                       , kannel_user = "kanneluser"
                                       , kannel_password = "kanneluser"
                                       , kannel_phone_number = 2381280899
                                       , kannel_url_parameters = "%p&%u&%b&%P")
        elif os_name == "Windows":
            gateway = GammuSMSGateway(gammu_db_connection_factory = self.gammu_connection_factory()
                                      , notification_server_address = "localhost"
                                      , notification_server_port = 20000
                                      , gammu_phone_number = 2381280899)
        else:
            _logger.error("Unable to recognize platform (%s). "
                          + "SMS Gateway not configured.", os_name)
        return gateway
    
    @Object
    def application_description_connection_factory(self):
        """Configures the database connection used to get the location of
        the application description XML files.
        """
        connection_factory = MySQLConnectionFactory(username = "root"
                                                    , password = "password"
                                                    , hostname = "localhost"
                                                    , db = "AppInfo")
        return connection_factory

    @Object
    def form_description_connection_factory(self):
        """Configures the database connection used to get the location of
        the application description XML files.
        """
        connection_factory = MySQLConnectionFactory(username = "root"
                                                    , password = "password"
                                                    , hostname = "localhost"
                                                    , db = "FormInfo")
        return connection_factory
    
    @Object
    def smsappstore_connection_factory(self):
        """Configures the database connection factory to be used to query
        SMSAppStore's database.
        """
        connection_factories = \
                {"Anti-Malaria Drug" : MySQLConnectionFactory(
                                            username = "root"
                                            , password = "password"
                                            , hostname = "localhost"
                                            , db = "Anti-Malaria Drug"),
                 "HIV/AIDS Diagnosis" : MySQLConnectionFactory(
                                            username = "root"
                                            , password = "password"
                                            , hostname = "localhost"
                                            , db = "HIV/AIDS Diagnosis"),
                }
        return connection_factories
    
    @Object
    def smsappstore_dispatcher(self):
        """Configures the ``SMSAppStoreDispatcher`` that will handle the
        binary messages sent by the client applications. Sets the
        instance of ``SMSGateway`` it will use and how long the threads that
        handle the communications from a given phone stay waiting (``None``
        means they wait forever). The timeout period is given in seconds.
        """
        sms_dispatcher = SMSAppStoreDispatcher(self.sms_gateway()
                , ApplicationReader(self.application_description_connection_factory())
                , FormReader(self.form_description_connection_factory())
                , self.smsappstore_connection_factory()
                , session_handler_timeout = 120)
        return sms_dispatcher
